package world;

import java.awt.Point;
import java.security.AllPermission;
import java.util.NoSuchElementException;

import javax.swing.tree.DefaultMutableTreeNode;

public class DFSTreeNode extends DefaultMutableTreeNode {

	private static final long serialVersionUID = 6044534575368940250L;
	private Point position;
	private boolean visited = false;

	public DFSTreeNode(Point position, boolean visited) {
		this.position = new Point(position);
		this.visited = visited;
	}
	
	public DFSTreeNode(Point position) {
		this.position = new Point(position);
		visited = false;
	}
	
	public boolean isVisited() {
		return visited;
	}
	
	public void setVisited() {
		this.visited = true;
	}
	
	public Point getPosition() {
		return position;
	}
	
	/**
	 * Checks if node contain child node of given position.
	 * @param position
	 * @return
	 */
	public boolean containsChildNode(Point position) {
		DFSTreeNode c = null; 
		try {
			c = (DFSTreeNode) getFirstChild();
		} catch (NoSuchElementException e) {
			return false;
		}
		
		for(; c != null; c = (DFSTreeNode) getChildAfter(c)) {
			if(c.getPosition().equals(position)) 
				return true;
		}
		
		return false;
	}
	
	public DFSTreeNode getFirstNotVisitedChild() {
		DFSTreeNode c = null; 
		try {
			c = (DFSTreeNode) getFirstChild();
		} catch (NoSuchElementException e) {
			return null;
		}
		
		for(; c != null; c = (DFSTreeNode) getChildAfter(c)) {
			if(!c.isVisited()) 
				return c;
		}
		
		return null;
	}
	
	public static boolean areAllPossibleChildrenVisited(DFSTreeNode n) {
		boolean result = true;
		DFSTreeNode c;
		
		try {
			c = (DFSTreeNode) n.getFirstChild();
		} catch (NoSuchElementException e) {
			c = null;
		}
		
		for(; c != null; c = (DFSTreeNode) n.getChildAfter(c)) {
			//if(!c.isVisited())
			if (!areAllPossibleChildrenVisited(c))
				return false;
			else 
				result = true;
		}
		
		return n.isVisited() && result;
	}
}
